/*
 * @Author: liusheng
 * @Date: 2022-05-02 17:24:41
 * @LastEditors: liusheng
 * @LastEditTime: 2022-05-02 18:06:20
 * @Description: 剑指 Offer II 051. 节点之和最大的路径
 * email:liusheng613@126.com
 * Copyright (c) 2022 by liusheng/liusheng, All Rights Reserved. 
 * 
 剑指 Offer II 051. 节点之和最大的路径
路径 被定义为一条从树中任意节点出发，沿父节点-子节点连接，达到任意节点的序列。同一个节点在一条路径序列中 至多出现一次 。该路径 至少包含一个 节点，且不一定经过根节点。

路径和 是路径中各节点值的总和。

给定一个二叉树的根节点 root ，返回其 最大路径和，即所有路径上节点值之和的最大值。

 

示例 1：

          1
         / \
        2   3

输入：root = [1,2,3]
输出：6
解释：最优路径是 2 -> 1 -> 3 ，路径和为 2 + 1 + 3 = 6
示例 2：
         -10
         / \
        9   20
           / \  
           15 7


输入：root = [-10,9,20,null,null,15,7]
输出：42
解释：最优路径是 15 -> 20 -> 7 ，路径和为 15 + 20 + 7 = 42
 

提示：

树中节点数目范围是 [1, 3 * 104]
-1000 <= Node.val <= 1000
 

注意：本题与主站 124 题相同： https://leetcode-cn.com/problems/binary-tree-maximum-path-sum/

通过次数8,729 提交次数18,913
 */

#include "header.h"
// Definition for a binary tree node.
struct TreeNode {
    int val;
      TreeNode *left;
      TreeNode *right;
      TreeNode() : val(0), left(nullptr), right(nullptr) {}
      TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
      TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
};

class Solution {
public:
    int maxPathSum(TreeNode* root) {
        NodeWeight(root);
        return maxSum;
    }
private:
    //dfs solution
    //traverse node preorder,caculate every node weight preorder,
    //update the maxPath through traverse
    // node weight:cur node value plus the max
    //of (left and right) node 
    int NodeWeight(TreeNode * root)
    {
        if (!root)
        {
            return 0;
        }
        
        int leftTreeWeight = max(NodeWeight(root->left),0);
        int rightTreeWeight = max(NodeWeight(root->right),0);
        
        int pathSum = leftTreeWeight + root->val + rightTreeWeight;
        
        //maxSum record the maxPathSum
        if (pathSum > maxSum)
        {
            maxSum = pathSum;
        }
        
        return root->val + max(leftTreeWeight,rightTreeWeight);
    }
private:
    int maxSum = INT_MIN;
};